package org.etherframework.tests.features.contextual
{
	import org.etherframework.core.EtherConfig;
	import org.etherframework.core.context.Context;
	import org.etherframework.tests.features.contextual.configs.HierarchicalConfig;
	import org.etherframework.tests.features.contextual.contexts.AnyContext;
	import org.etherframework.tests.features.contextual.processors.ChildModuleProcessor;
	import org.etherframework.tests.features.contextual.processors.ModuleProcessor;
	import org.etherframework.tests.features.contextual.processors.NonContextProcessor;
	import org.etherframework.tests.features.contextual.processors.TopModuleProcessor;
	import org.etherframework.tests.utils.ModuleHierarchy;
	import org.etherframework.tests.utils.TestUtility;
	import org.etherframework.wire.ProcessorFactory;
	import org.fluint.uiImpersonation.UIImpersonator;
	import org.hamcrest.assertThat;
	import org.hamcrest.object.instanceOf;
	import org.hamcrest.object.nullValue;

	public class when_using_contextual_processors
	{	
		private static var _testUtility:TestUtility = new TestUtility();
		private static var _hiearchy:ModuleHierarchy;
		
		[BeforeClass]
		public static function setUpBeforeClass():void
		{
			const configs:Vector.<EtherConfig> = new Vector.<EtherConfig>();
			configs.push(new HierarchicalConfig(), new HierarchicalConfig(), new HierarchicalConfig()); 
			_hiearchy = _testUtility.createHierarchy(configs);
			UIImpersonator.addChild(_hiearchy.module.view);
			
			_hiearchy.module.wiring.addProcessor(new ProcessorFactory(NonContextProcessor));
			_hiearchy.module.wiring.contextual(new AnyContext()).addProcessor(new ProcessorFactory(TopModuleProcessor));
			_hiearchy.next().module.wiring.contextual(new AnyContext()).addProcessor(new ProcessorFactory(ModuleProcessor));
			_hiearchy.next().next().module.wiring.contextual(new AnyContext()).addProcessor(new ProcessorFactory(ChildModuleProcessor));
		}
		
		[AfterClass]
		public static function tearDownAfterClass():void
		{
			UIImpersonator.removeAllChildren();
			_testUtility.dispose();
		}
		
		[Test(order=1)]
		public function it_should_be_resolved():void
		{
			assertThat(_hiearchy.module.wiring.createProcessor("NonContextProcessor"), instanceOf(NonContextProcessor));
			assertThat(_hiearchy.module.wiring.contextual(new AnyContext()).createProcessor("TopModuleProcessor"), instanceOf(TopModuleProcessor));
			assertThat(_hiearchy.next().module.wiring.contextual(new AnyContext()).createProcessor("ModuleProcessor"), instanceOf(ModuleProcessor));
			assertThat(_hiearchy.next().next().module.wiring.contextual(new AnyContext()).createProcessor("ChildModuleProcessor"), instanceOf(ChildModuleProcessor));
			
			assertThat(_hiearchy.module.wiring.createProcessor("TopModuleProcessor"), nullValue());
			assertThat(_hiearchy.next().module.wiring.createProcessor("ModuleProcessor"), nullValue());
			assertThat(_hiearchy.next().next().module.wiring.createProcessor("ChildModuleProcessor"), nullValue());
		}
		
		[Test(order=2)]
		public function it_should_be_resolved_in_default_context_through_custom():void
		{
			assertThat(_hiearchy.info.bridge.facade.contextual(new AnyContext()).createProcessor("NonContextProcessor"), instanceOf(NonContextProcessor));
			assertThat(_hiearchy.next().info.bridge.facade.contextual(new AnyContext()).createProcessor("NonContextProcessor"), instanceOf(NonContextProcessor));
			assertThat(_hiearchy.next().next().info.bridge.facade.contextual(new AnyContext()).createProcessor("NonContextProcessor"), instanceOf(NonContextProcessor));
		}
		
		
	}
}